﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace DlrBasic.Parser
{
    static class Keywords
    {
        internal const string AndKeyword = "AND";
        internal const string OrKeyword = "OR";
        internal const string ModKeyword = "MOD";
        internal const string NotKeyword = "NOT";
        internal const string XorKeyword = "XOR";
        internal const string ImpKeyword = "IMP";
        internal const string EqvKeyword = "EQV";
        internal const string PrintKeyword = "PRINT";
        internal const string InputKeyword = "INPUT";
        internal const string EndKeyword = "END";
        internal const string GotoKeyword = "GOTO";
        internal const string OnKeyword = "ON";
        internal const string GosubKeyword = "GOSUB";
        internal const string ReturnKeyword = "RETURN";
        internal const string IfKeyword = "IF";
        internal const string ThenKeyword = "THEN";
        internal const string ElseKeyword = "ELSE";
        internal const string ForKeyword = "FOR";
        internal const string NextKeyword = "NEXT";
        internal const string StepKeyword = "STEP";
        internal const string WhileKeyword = "WHILE";
        internal const string WendKeyword = "WEND";
        internal const string ToKeyword = "TO";
        internal const string ClsKeyword = "CLS";
        internal const string ClearKeyword = "CLEAR";
        internal const string LineKeyword = "LINE";
        internal const string OpenKeyword = "OPEN";
        internal const string CloseKeyword = "CLOSE";
        internal const string RandomizeKeyword = "RANDOMIZE";
        internal const string DefKeyword = "DEF";
        internal const string DimKeyword = "DIM";
        internal const string LetKeyword = "LET";
        internal const string RemKeyword = "REM";
        internal const string UsingKeyword = "USING";
        internal const string BeepKeyword = "BEEP";
        internal const string MatKeyword = "MAT";
        internal const string ZerKeyword = "ZER";
        internal const string OfKeyword = "OF";

        internal const int AndKeywordId = 1;
        internal const int OrKeywordId = 2;
        internal const int ModKeywordId = 3;
        internal const int NotKeywordId = 4;
        internal const int XorKeywordId = 5;
        internal const int ImpKeywordId = 6;
        internal const int EqvKeywordId = 7;
        internal const int PrintKeywordId = 8;
        internal const int InputKeywordId = 9;
        internal const int EndKeywordId = 10;
        internal const int GotoKeywordId = 11;
        internal const int OnKeywordId = 12;
        internal const int GosubKeywordId = 13;
        internal const int ReturnKeywordId = 14;
        internal const int IfKeywordId = 15;
        internal const int ThenKeywordId = 16;
        internal const int ElseKeywordId = 17;
        internal const int ForKeywordId = 18;
        internal const int NextKeywordId = 19;
        internal const int StepKeywordId = 20;
        internal const int WhileKeywordId = 21;
        internal const int WendKeywordId = 22;
        internal const int ToKeywordId = 23;
        internal const int ClsKeywordId = 24;
        internal const int ClearKeywordId = 25;
        internal const int LineKeywordId = 26;
        internal const int OpenKeywordId = 27;
        internal const int CloseKeywordId = 28;
        internal const int RandomizeKeywordId = 29;
        internal const int DefKeywordId = 30;
        internal const int DimKeywordId = 31;
        internal const int LetKeywordId = 32;
        internal const int RemKeywordId = 33;
        internal const int UsingKeywordId = 34;
        internal const int BeepKeywordId = 35;
        internal const int MatKeywordId = 36;
        internal const int ZerKeywordId = 37;
        internal const int OfKeywordId = 38;

        static Dictionary<string, int> IdMap;

        static Keywords()
        {
            IdMap = new Dictionary<string, int>(StringComparer.InvariantCultureIgnoreCase);
            Type keywordsType = typeof(Keywords);
            foreach (FieldInfo field in keywordsType.GetFields(BindingFlags.Static | BindingFlags.NonPublic))
            {
                if (field.FieldType == typeof(string))
                {
                    IdMap[(string)field.GetValue(null)] =
                        (int)keywordsType.GetField(field.Name + "Id", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null);
                }
            }
        }

        internal static bool IsKeyword(string name)
        {
            return IdMap.ContainsKey(name);
        }

        internal static int GetKeywordId(string name)
        {
            return IdMap[name];
        }

        internal static bool TryGetKeywordId(string name, out int id)
        {
            return IdMap.TryGetValue(name, out id);
        }
    }
}
